﻿Imports System.Net
Public Class IPv6
    ' Methods
    Public Sub New(ByVal IPAddress As String, ByVal ScopeID As Integer)
        Me._GivenIPAddress = IPAddress
        Me._ScopeID = ScopeID
        Me._IPAddressBytes = Me.GetIPAddressBytes(Me._GivenIPAddress)
        Me._ScopeIDBytes = Me.GetScopeIDBytes(Me._ScopeID)
        Me._MaxHostes = Me.GetMaxHostes(Me._ScopeID)
        Me.GetAddressType(Me.GetAddressByteString(Me._IPAddressBytes))
        If (Me._AddressType = IPAddressType.Unicast) Then
            If (Me._IPAddressBytes.Length <> Me._ScopeIDBytes.Length) Then
                Throw New ArgumentException("Lengths of IP Address and Subnetmask do not match")
            End If
            Me._LastAddress = Me.GetLastAddress(Me._IPAddressBytes, Me._ScopeIDBytes)
            Me._NetworkAddress = Me.GetNetworkAddress(Me._IPAddressBytes, Me._ScopeIDBytes)
        End If
    End Sub

    Private Function GetAddressByteString(ByVal IPAddressBytes As Byte()) As String
        Dim str As String = ""
        Dim length As Integer = 0
        Dim i As Integer
        For i = 0 To &H10 - 1
            length = Convert.ToString(IPAddressBytes(i), 2).Length
            If (length < 8) Then
                Dim j As Integer
                For j = length To 8 - 1
                    str = (str & "0")
                Next j
            End If
            str = If((str & Convert.ToString(IPAddressBytes(i), 2)) <> Nothing, (str & Convert.ToString(IPAddressBytes(i), 2)), "")
        Next i
        Return str
    End Function

    Private Sub GetAddressType(ByVal AddressByteString As String)
        Dim str As String = "00000000"
        Dim str2 As String = "0000001"
        Dim str3 As String = "0000010"
        Dim str4 As String = "001"
        Dim str5 As String = "1111111010"
        Dim str6 As String = "1111111011"
        Dim str7 As String = "11111111"
        If str6.Equals(AddressByteString.Substring(0, 10)) Then
            Me._AddressType = IPAddressType.Unicast
            Me._UnicastType = IPUnicastType.Sitelocal
        ElseIf str4.Equals(AddressByteString.Substring(0, 3)) Then
            Me._AddressType = IPAddressType.Unicast
            Me._UnicastType = IPUnicastType.Global
        ElseIf str7.Equals(AddressByteString.Substring(0, 8)) Then
            Me._AddressType = IPAddressType.Multicast
        ElseIf str5.Equals(AddressByteString.Substring(0, 10)) Then
            Me._AddressType = IPAddressType.Unicast
            Me._UnicastType = IPUnicastType.Linklocal
        ElseIf str.Equals(AddressByteString.Substring(0, 8)) Then
            Me._AddressType = IPAddressType.Reserved
        ElseIf str3.Equals(AddressByteString.Substring(0, 7)) Then
            Me._AddressType = IPAddressType.IPXAllocation
        ElseIf str2.Equals(AddressByteString.Substring(0, 7)) Then
            Me._AddressType = IPAddressType.NSAPAllocation
        Else
            Me._AddressType = IPAddressType.Unassigned
        End If
    End Sub

    Private Function GetIPAddressBytes(ByVal IPAddress As String) As Byte()
        Dim addressBytes As Byte()
        Try
            addressBytes = System.Net.IPAddress.Parse(IPAddress).GetAddressBytes
        Catch ex As Exception
            Throw New ArgumentException("The given String is not an IP Address")
        End Try
        Return addressBytes
    End Function

    Private Function GetLastAddress(ByVal _IPAddressBytes As Byte(), ByVal _ScopeIDBytes As Byte()) As IPAddress
        Dim address As Byte() = New Byte(_IPAddressBytes.Length - 1) {}
        Dim i As Integer
        For i = 0 To address.Length - 1
            address(i) = CByte((_IPAddressBytes(i) Or (_ScopeIDBytes(i) Xor &HFF)))
        Next i
        Return New IPAddress(address)
    End Function

    Private Function GetMaxHostes(ByVal ScopeID As Integer) As Double
        Dim num As Integer = (&H80 - ScopeID)
        Return Math.Pow(2, Convert.ToDouble(num))
    End Function

    Private Function GetNetworkAddress(ByVal _IPAddressBytes As Byte(), ByVal _ScopeIDBytes As Byte()) As IPAddress
        Dim address As Byte() = New Byte(_IPAddressBytes.Length - 1) {}
        Dim i As Integer
        For i = 0 To address.Length - 1
            address(i) = CByte((_IPAddressBytes(i) And _ScopeIDBytes(i)))
        Next i
        Return New IPAddress(address)
    End Function

    Public Function GetNetworkRange() As List(Of IPAddress)
        Dim addressBytes As Byte() = Me._NetworkAddress.GetAddressBytes
        addressBytes(15) = CByte((addressBytes(15) + 1))
        Dim list As New List(Of IPAddress) From {New IPAddress(addressBytes)}
        Dim i As Double
        For i = 1 To Me._MaxHostes - 1
            If (addressBytes(15) < &HFF) Then
                addressBytes(15) = CByte((addressBytes(15) + 1))
            ElseIf ((addressBytes(15) = &HFF) AndAlso (addressBytes(14) < &HFF)) Then
                addressBytes(14) = CByte((addressBytes(14) + 1))
                addressBytes(15) = 0
            ElseIf (((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso (addressBytes(13) < &HFF)) Then
                addressBytes(13) = CByte((addressBytes(13) + 1))
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso (addressBytes(13) = &HFF)) AndAlso (addressBytes(12) < &HFF)) Then
                addressBytes(12) = CByte((addressBytes(12) + 1))
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (addressBytes(11) < &HFF)) Then
                addressBytes(11) = CByte((addressBytes(11) + 1))
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf (((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (addressBytes(11) = &HFF)) AndAlso (addressBytes(10) < &HFF)) Then
                addressBytes(10) = CByte((addressBytes(10) + 1))
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf (((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso ((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF))) AndAlso (addressBytes(9) < &HFF)) Then
                addressBytes(9) = CByte((addressBytes(9) + 1))
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf (((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso (addressBytes(9) = &HFF))) AndAlso (addressBytes(8) < &HFF)) Then
                addressBytes(8) = CByte((addressBytes(8) + 1))
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf (((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso (addressBytes(7) < &HFF)) Then
                addressBytes(7) = CByte((addressBytes(7) + 1))
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso (addressBytes(7) = &HFF)) AndAlso (addressBytes(6) < &HFF)) Then
                addressBytes(6) = CByte((addressBytes(6) + 1))
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso ((addressBytes(7) = &HFF) AndAlso (addressBytes(6) = &HFF))) AndAlso (addressBytes(5) < &HFF)) Then
                addressBytes(5) = CByte((addressBytes(5) + 1))
                addressBytes(6) = 0
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso (((addressBytes(7) = &HFF) AndAlso (addressBytes(6) = &HFF)) AndAlso (addressBytes(5) = &HFF))) AndAlso (addressBytes(4) < &HFF)) Then
                addressBytes(4) = CByte((addressBytes(4) + 1))
                addressBytes(5) = 0
                addressBytes(6) = 0
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso (((addressBytes(7) = &HFF) AndAlso (addressBytes(6) = &HFF)) AndAlso ((addressBytes(5) = &HFF) AndAlso (addressBytes(4) = &HFF)))) AndAlso (addressBytes(3) < &HFF)) Then
                addressBytes(3) = CByte((addressBytes(3) + 1))
                addressBytes(4) = 0
                addressBytes(5) = 0
                addressBytes(6) = 0
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso ((((addressBytes(7) = &HFF) AndAlso (addressBytes(6) = &HFF)) AndAlso ((addressBytes(5) = &HFF) AndAlso (addressBytes(4) = &HFF))) AndAlso (addressBytes(3) = &HFF))) AndAlso (addressBytes(2) < &HFF)) Then
                addressBytes(2) = CByte((addressBytes(2) + 1))
                addressBytes(3) = 0
                addressBytes(4) = 0
                addressBytes(5) = 0
                addressBytes(6) = 0
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso ((((addressBytes(7) = &HFF) AndAlso (addressBytes(6) = &HFF)) AndAlso ((addressBytes(5) = &HFF) AndAlso (addressBytes(4) = &HFF))) AndAlso ((addressBytes(3) = &HFF) AndAlso (addressBytes(2) = &HFF)))) AndAlso (addressBytes(1) < &HFF)) Then
                addressBytes(1) = CByte((addressBytes(1) + 1))
                addressBytes(2) = 0
                addressBytes(3) = 0
                addressBytes(4) = 0
                addressBytes(5) = 0
                addressBytes(6) = 0
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            Else
                If ((((((addressBytes(15) <> &HFF) OrElse (addressBytes(14) <> &HFF)) OrElse ((addressBytes(13) <> &HFF) OrElse (addressBytes(12) <> &HFF))) OrElse (((addressBytes(11) <> &HFF) OrElse (addressBytes(10) <> &HFF)) OrElse ((addressBytes(9) <> &HFF) OrElse (addressBytes(8) <> &HFF)))) OrElse ((((addressBytes(7) <> &HFF) OrElse (addressBytes(6) <> &HFF)) OrElse ((addressBytes(5) <> &HFF) OrElse (addressBytes(4) <> &HFF))) OrElse (((addressBytes(3) <> &HFF) OrElse (addressBytes(2) <> &HFF)) OrElse (addressBytes(1) <> &HFF)))) OrElse (addressBytes(0) >= &HFF)) Then
                    Throw New ArgumentOutOfRangeException
                End If
                addressBytes(0) = CByte((addressBytes(0) + 1))
                addressBytes(1) = 0
                addressBytes(2) = 0
                addressBytes(3) = 0
                addressBytes(4) = 0
                addressBytes(5) = 0
                addressBytes(6) = 0
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            End If
            list.Add(New IPAddress(addressBytes))
        Next i
        Return list
    End Function

    Public Function GetNetworkRange(ByVal FirstAddress As IPAddress, ByVal Count As Integer) As List(Of IPAddress)
        If (Count > Me._MaxHostes) Then
            Throw New ArgumentOutOfRangeException("Count", "")
        End If
        Dim addressBytes As Byte() = FirstAddress.GetAddressBytes
        Dim list As New List(Of IPAddress) From {New IPAddress(addressBytes)}
        Dim i As Double
        For i = 1 To Count - 1
            If (addressBytes(15) < &HFF) Then
                addressBytes(15) = CByte((addressBytes(15) + 1))
            ElseIf ((addressBytes(15) = &HFF) AndAlso (addressBytes(14) < &HFF)) Then
                addressBytes(14) = CByte((addressBytes(14) + 1))
                addressBytes(15) = 0
            ElseIf (((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso (addressBytes(13) < &HFF)) Then
                addressBytes(13) = CByte((addressBytes(13) + 1))
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso (addressBytes(13) = &HFF)) AndAlso (addressBytes(12) < &HFF)) Then
                addressBytes(12) = CByte((addressBytes(12) + 1))
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (addressBytes(11) < &HFF)) Then
                addressBytes(11) = CByte((addressBytes(11) + 1))
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf (((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (addressBytes(11) = &HFF)) AndAlso (addressBytes(10) < &HFF)) Then
                addressBytes(10) = CByte((addressBytes(10) + 1))
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf (((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso ((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF))) AndAlso (addressBytes(9) < &HFF)) Then
                addressBytes(9) = CByte((addressBytes(9) + 1))
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf (((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso (addressBytes(9) = &HFF))) AndAlso (addressBytes(8) < &HFF)) Then
                addressBytes(8) = CByte((addressBytes(8) + 1))
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf (((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso (addressBytes(7) < &HFF)) Then
                addressBytes(7) = CByte((addressBytes(7) + 1))
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso (addressBytes(7) = &HFF)) AndAlso (addressBytes(6) < &HFF)) Then
                addressBytes(6) = CByte((addressBytes(6) + 1))
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso ((addressBytes(7) = &HFF) AndAlso (addressBytes(6) = &HFF))) AndAlso (addressBytes(5) < &HFF)) Then
                addressBytes(5) = CByte((addressBytes(5) + 1))
                addressBytes(6) = 0
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso (((addressBytes(7) = &HFF) AndAlso (addressBytes(6) = &HFF)) AndAlso (addressBytes(5) = &HFF))) AndAlso (addressBytes(4) < &HFF)) Then
                addressBytes(4) = CByte((addressBytes(4) + 1))
                addressBytes(5) = 0
                addressBytes(6) = 0
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso (((addressBytes(7) = &HFF) AndAlso (addressBytes(6) = &HFF)) AndAlso ((addressBytes(5) = &HFF) AndAlso (addressBytes(4) = &HFF)))) AndAlso (addressBytes(3) < &HFF)) Then
                addressBytes(3) = CByte((addressBytes(3) + 1))
                addressBytes(4) = 0
                addressBytes(5) = 0
                addressBytes(6) = 0
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso ((((addressBytes(7) = &HFF) AndAlso (addressBytes(6) = &HFF)) AndAlso ((addressBytes(5) = &HFF) AndAlso (addressBytes(4) = &HFF))) AndAlso (addressBytes(3) = &HFF))) AndAlso (addressBytes(2) < &HFF)) Then
                addressBytes(2) = CByte((addressBytes(2) + 1))
                addressBytes(3) = 0
                addressBytes(4) = 0
                addressBytes(5) = 0
                addressBytes(6) = 0
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            ElseIf ((((((addressBytes(15) = &HFF) AndAlso (addressBytes(14) = &HFF)) AndAlso ((addressBytes(13) = &HFF) AndAlso (addressBytes(12) = &HFF))) AndAlso (((addressBytes(11) = &HFF) AndAlso (addressBytes(10) = &HFF)) AndAlso ((addressBytes(9) = &HFF) AndAlso (addressBytes(8) = &HFF)))) AndAlso ((((addressBytes(7) = &HFF) AndAlso (addressBytes(6) = &HFF)) AndAlso ((addressBytes(5) = &HFF) AndAlso (addressBytes(4) = &HFF))) AndAlso ((addressBytes(3) = &HFF) AndAlso (addressBytes(2) = &HFF)))) AndAlso (addressBytes(1) < &HFF)) Then
                addressBytes(1) = CByte((addressBytes(1) + 1))
                addressBytes(2) = 0
                addressBytes(3) = 0
                addressBytes(4) = 0
                addressBytes(5) = 0
                addressBytes(6) = 0
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            Else
                If ((((((addressBytes(15) <> &HFF) OrElse (addressBytes(14) <> &HFF)) OrElse ((addressBytes(13) <> &HFF) OrElse (addressBytes(12) <> &HFF))) OrElse (((addressBytes(11) <> &HFF) OrElse (addressBytes(10) <> &HFF)) OrElse ((addressBytes(9) <> &HFF) OrElse (addressBytes(8) <> &HFF)))) OrElse ((((addressBytes(7) <> &HFF) OrElse (addressBytes(6) <> &HFF)) OrElse ((addressBytes(5) <> &HFF) OrElse (addressBytes(4) <> &HFF))) OrElse (((addressBytes(3) <> &HFF) OrElse (addressBytes(2) <> &HFF)) OrElse (addressBytes(1) <> &HFF)))) OrElse (addressBytes(0) >= &HFF)) Then
                    Throw New ArgumentOutOfRangeException
                End If
                addressBytes(0) = CByte((addressBytes(0) + 1))
                addressBytes(1) = 0
                addressBytes(2) = 0
                addressBytes(3) = 0
                addressBytes(4) = 0
                addressBytes(5) = 0
                addressBytes(6) = 0
                addressBytes(7) = 0
                addressBytes(8) = 0
                addressBytes(9) = 0
                addressBytes(10) = 0
                addressBytes(11) = 0
                addressBytes(12) = 0
                addressBytes(13) = 0
                addressBytes(14) = 0
                addressBytes(15) = 0
            End If
            Dim item As New IPAddress(addressBytes)
            If Not Me.IsInSameNetworkSegment(item.ToString, Me._ScopeID) Then
                Throw New ArgumentOutOfRangeException("Count", "")
            End If
            list.Add(item)
        Next i
        Return list
    End Function

    Private Function GetScopeIDBytes(ByVal ScopeID As Integer) As Byte()
        Dim num As Integer
        If (ScopeID >= &H80) Then
            Throw New ArgumentException("The given Int is not an ScopeID")
        End If
        Dim str As String = ""
        'num()
        For num = 0 To ScopeID - 1
            str = (str & "1")
        Next num
        'num()
        For num = 0 To (&H80 - ScopeID) - 1
            str = (str & "0")
        Next num
        Dim strArray As String() = New String() {str.Substring(1, 8), str.Substring(8, 8), str.Substring(&H10, 8), str.Substring(&H18, 8), str.Substring(&H20, 8), str.Substring(40, 8), str.Substring(&H30, 8), str.Substring(&H38, 8), str.Substring(&H40, 8), str.Substring(&H48, 8), str.Substring(80, 8), str.Substring(&H58, 8), str.Substring(&H60, 8), str.Substring(&H68, 8), str.Substring(&H70, 8), str.Substring(120, 8)}
        Dim buffer As Byte() = New Byte(&H10 - 1) {}
        'num()
        For num = 0 To &H10 - 1
            buffer(num) = Convert.ToByte(strArray(num), 2)
        Next num
        Return buffer
    End Function

    Public Function IsInSameNetworkSegment(ByVal IPAddress As String, ByVal ScopeID As Integer) As Boolean
        Return Me.GetNetworkAddress(Me.GetIPAddressBytes(IPAddress), Me.GetScopeIDBytes(ScopeID)).Equals(Me._NetworkAddress)
    End Function


    ' Properties
    Public ReadOnly Property AddressType As IPAddressType
        Get
            Return Me._AddressType
        End Get
    End Property

    Public ReadOnly Property GivenIPAddress As String
        Get
            Return Me._GivenIPAddress
        End Get
    End Property

    Public ReadOnly Property GivenScopeID As Integer
        Get
            Return Me._ScopeID
        End Get
    End Property

    Public ReadOnly Property LastAddress As IPAddress
        Get
            Return Me._LastAddress
        End Get
    End Property

    Public ReadOnly Property MaxHostes As Double
        Get
            Return Me._MaxHostes
        End Get
    End Property

    Public ReadOnly Property NetworkAddress As IPAddress
        Get
            Return Me._NetworkAddress
        End Get
    End Property

    Public ReadOnly Property UnicastType As IPUnicastType
        Get
            Return Me._UnicastType
        End Get
    End Property


    ' Fields
    Private _AddressType As IPAddressType
    Private _GivenIPAddress As String
    Private _IPAddressBytes As Byte()
    Private _LastAddress As IPAddress
    Private _MaxHostes As Double
    Private _NetworkAddress As IPAddress
    Private _ScopeID As Integer
    Private _ScopeIDBytes As Byte()
    Private _UnicastType As IPUnicastType

    ' Nested Types
    Public Enum IPAddressType
        ' Fields
        Anycast = 2
        IPXAllocation = 3
        Multicast = 1
        NSAPAllocation = 4
        Reserved = 5
        Unassigned = 6
        Unicast = 0
    End Enum

    Public Enum IPUnicastType
        ' Fields
        [Global] = 1
        Linklocal = 2
        [NULL] = 0
        Sitelocal = 3
    End Enum

End Class
